package org.xq.softcup.mq.remoting.invoker.router.impl;

import org.xq.softcup.mq.remoting.invoker.router.XQRpcLoadBalance;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class XQRpcLoadBalanceLFUStrategy extends XQRpcLoadBalance
{
    private ConcurrentHashMap<String, HashMap<String, Integer>> jobLfuMap = new ConcurrentHashMap();
    private long CACHE_VALID_TIME = 0L;

    public String doRoute(String serviceKey, TreeSet<String> addressSet)
    {
        if (System.currentTimeMillis() > this.CACHE_VALID_TIME)
        {
            this.jobLfuMap.clear();
            this.CACHE_VALID_TIME = (System.currentTimeMillis() + 86400000L);
        }
        HashMap<String, Integer> lfuItemMap = (HashMap)this.jobLfuMap.get(serviceKey);
        if (lfuItemMap == null)
        {
            lfuItemMap = new HashMap();
            this.jobLfuMap.putIfAbsent(serviceKey, lfuItemMap);
        }
        for (String address : addressSet) {
            if ((!lfuItemMap.containsKey(address)) || (((Integer)lfuItemMap.get(address)).intValue() > 1000000)) {
                lfuItemMap.put(address, Integer.valueOf(0));
            }
        }
        List<Map.Entry<String, Integer>> lfuItemList = new ArrayList(lfuItemMap.entrySet());
        Collections.sort(lfuItemList, new Comparator<Map.Entry<String, Integer>>()
        {
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2)
            {
                return ((Integer)o1.getValue()).compareTo((Integer)o2.getValue());
            }
        });
        Map.Entry<String, Integer> addressItem = (Map.Entry)lfuItemList.get(0);
        String minAddress = (String)addressItem.getKey();
        addressItem.setValue(Integer.valueOf(((Integer)addressItem.getValue()).intValue() + 1));

        return minAddress;
    }

    public String route(String serviceKey, TreeSet<String> addressSet)
    {
        String finalAddress = doRoute(serviceKey, addressSet);
        return finalAddress;
    }
}
